﻿Imports System.Text.RegularExpressions
Imports System.Drawing
Imports System.Net

'Credits:
' - Acidic / Fr[o]zen
' - Tedd

'Stats Used In GetStat
Public Enum Stats
    STRENGTH
    AGILITY
    STAMINA
    INTELLECT
    SPIRIT
    MASTERY
    ATTACK_POWER
    EXPERTISE
    CRIT
    HASTE
    HIT
    RESILIENCE
End Enum

'Talents used in GetTalent
Public Enum Talent
    Primary
    Secondary
End Enum

'Raids for use with GetRaidCompletion
Public Enum Raids
    MC
    BWL
    AQ10
    AQ40
    Kar
    Mag
    Gru
    SSC
    TK
    MH
    BT
    SP
    VoA
    Nax
    OS
    EoE
    Uld
    Ony
    ToC
    ICC
    RS
    BH
    BD
    BoT
    TFW
    FL
End Enum

'Raid types for use with raid completion
Public Enum Difficulty
    Normal
    Heroic
End Enum

'Raid completion types
Public Enum RaidCompletion
    Incomplete
    InProgress
    Completed
End Enum

Public Enum Brackets
    Twos
    Threes
    Fives
    RBGs
End Enum

Public Class ArmoryCredential
    Private _name As String
    Friend Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Private _realm As String
    Friend Property Realm() As String
        Get
            Return _realm
        End Get
        Set(ByVal value As String)
            _realm = value
        End Set
    End Property

    Sub New(ByVal Name As String, ByVal Realm As String)
        _name = Name
        _realm = Realm.Replace(" ", "-").ToLower
    End Sub
End Class

Public Class WoWArmory
    Sub New(ByVal ArmoryCredentials As ArmoryCredential)
        If Not ArmoryCredentials.Name Is Nothing And Not ArmoryCredentials.Realm Is Nothing Then
            Try
                ArmoryInfo = (New WebClient).DownloadString("http://us.battle.net/wow/en/character/" & ArmoryCredentials.Realm & "/" & ArmoryCredentials.Name & "/advanced")
                ArmoryCred = ArmoryCredentials
            Catch
                Throw New WebException("Invalid credentials or could not connect to database")
            End Try
        End If
    End Sub
#Region "DECLARATIONS"
    Private ArmoryInfo$
    Private ArmoryCred As ArmoryCredential
#End Region

#Region "STATS"
    'Get Base Strength
    Function GetStat(ByVal stat As Stats) As Decimal
        Try
            Select Case stat
                Case Stats.STRENGTH
                    Return Regex.Split(ArmoryInfo, "strTotal"": ")(1).Split(",")(0)
                Case Stats.AGILITY
                    Return Regex.Split(ArmoryInfo, "agiTotal"": ")(1).Split(",")(0)
                Case Stats.STAMINA
                    Return Regex.Split(ArmoryInfo, "staTotal"": ")(1).Split(",")(0)
                Case Stats.INTELLECT
                    Return Regex.Split(ArmoryInfo, "intTotal"": ")(1).Split(",")(0)
                Case Stats.SPIRIT
                    Return Regex.Split(ArmoryInfo, "sprTotal"": ")(1).Split(",")(0)
                Case Stats.MASTERY
                    Return Regex.Split(ArmoryInfo, "mastery"": ")(1).Split(",")(0).Substring(0, 5) 'Substring to limit to 4 decimal places
                Case Stats.ATTACK_POWER
                    Return Regex.Split(ArmoryInfo, "atkPowerTotal"": ")(1).Split(",")(0)
                Case Else
                    Return Nothing
            End Select
        Catch
            Return Nothing
        End Try
    End Function
#End Region

#Region "GUILD"
    'Get Guild
    Function GetGuildName() As String
        Try
            Return Regex.Split(ArmoryInfo, "/wow/en/guild/" & ArmoryCred.Realm & "/")(1).Split("/")(0).Replace("%20", " ")
        Catch
            Return Nothing
        End Try
    End Function

    'Is in a guild?
    Function HasGuild() As Boolean
        If ArmoryInfo.Contains("/wow/en/guild/" & ArmoryCred.Realm) Then
            Return True
        Else
            Return False
        End If
    End Function
#End Region

#Region "PVP"
    'Get BattleGround Rating
    Function GetBGRating() As Integer
        Try
            Return Regex.Split(ArmoryInfo, "Battleground rating</span><span class=""value"">")(1).Split("<")(0)
        Catch
            Return Nothing
        End Try
    End Function

    'Get Honorable Kills
    Function GetHonorableKills() As Integer
        Try
            Return Regex.Split(ArmoryInfo, "Honorable kills</span><span class=""value"">")(1).Split("<")(0)
        Catch
            Return Nothing
        End Try
    End Function

    Function GetArenaRating(ByVal TeamBracket As Brackets)
        Try
            Select Case TeamBracket
                Case Brackets.Twos
                    If Regex.Split(Regex.Split(ArmoryInfo, "<h2>2v2</h2>")(1), "</div")(1).Contains("won") Then
                        Return Regex.Split(Regex.Split(ArmoryInfo, "<h2>2v2</h2>")(1), "Personal rating"">")(1).Split("<")(0) : Else : Return Nothing
                    End If
                Case Brackets.Threes
                    If Regex.Split(Regex.Split(ArmoryInfo, "<h2>3v3</h2>")(1), "</div")(1).Contains("won") Then
                        Return Regex.Split(Regex.Split(ArmoryInfo, "<h2>3v3</h2>")(1), "Personal rating"">")(1).Split("<")(0) : Else : Return Nothing
                    End If
                Case Brackets.Fives
                    If Regex.Split(Regex.Split(ArmoryInfo, "<h2>5v5</h2>")(1), "</div").Contains("won") Then
                        Return Regex.Split(Regex.Split(ArmoryInfo, "<h2>5v5</h2>")(1), "Personal rating"">")(1).Split("<")(0) : Else : Return Nothing
                    End If
                Case Brackets.RBGs
                    If (Regex.Split(ArmoryInfo, "Battleground rating</span><span class=""value"">")(1).Split("<")(0)) <> (Nothing Or "0") Then
                        Return Regex.Split(ArmoryInfo, "Battleground rating</span><span class=""value"">")(1).Split("<")(0) : Else : Return Nothing
                    End If
            End Select
        Catch ex As Exception
            Return Nothing
        End Try
        Return Nothing
    End Function
#End Region

#Region "General Info"
    'Get Average Item Level
    Function GetItemLevel() As Integer
        Return Regex.Split(ArmoryInfo, "equipped"">")(1).Split("<")(0)
    End Function

    'Get Character Level
    Function GetCharacterLevel() As Integer
        Return Regex.Split(ArmoryInfo, "class=""level""><strong>")(1).Split("<")(0)
    End Function

    'Get Race
    Function GetRace() As String
        Return Regex.Split(ArmoryInfo, "class=""race"">")(1).Split("<")(0)
    End Function

    'Get Class
    Function GetClass() As String
        Return Regex.Split(ArmoryInfo, "class=""class"">")(1).Split("<")(0)
    End Function

    'Get Achievement Count
    Function GetAchievementPoints() As Integer
        Return Regex.Split(ArmoryInfo, "/achievement"">")(1).Split("<")(0)
    End Function

    'Get Health
    Function GetHealth() As Integer
        Return Regex.Split(ArmoryInfo, """health""><span class=""name"">Health</span><span class=""value"">")(1).Split("<")(0)
    End Function

    'Get Title
    Function GetTitle() As String
        Try
            If Not Regex.Split(ArmoryInfo, "class=""title"">")(1).Split("<")(0).Contains("#") Then
                Return Regex.Split(ArmoryInfo, "class=""title"">")(1).Split("<")(0)
            Else
                Return Nothing
            End If
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

    'Get either primary or secondary talent
    Function GetTalent(ByVal Slot As Talent) As String
        Select Case Slot
            Case Talent.Primary
                Return Regex.Split(Regex.Split(ArmoryInfo, "/talent/primary")(1), "name"">")(1).Split("<")(0)
            Case Talent.Secondary
                Return Regex.Split(Regex.Split(ArmoryInfo, "/talent/secondary")(1), "name"">")(1).Split("<")(0)
            Case Else
                Return Nothing
        End Select
    End Function

    'Gets Characters Talent Build - Feral Druid ( Druid w/ Talents all into Feral tree, would return "Feral Combat"
    Function GetBuild() As String
        Return Regex.Split(Regex.Split(ArmoryInfo, "name-build"">")(1), "name"">")(1).Split("<")(0)
    End Function

    'Gets the character image
    Function GetCharacterImage() As Bitmap
        Dim B() As Byte = (New WebClient).DownloadData(Regex.Split(ArmoryInfo, ".profile-wrapper { background-image:")(1).Split("""")(1).Split("""")(0))
        Dim I As New IO.MemoryStream(B)
        Return Bitmap.FromStream(I)
    End Function
#End Region

#Region "Raid Info"
    'Get Raid Completion
    Function GetRaidCompletion(ByVal Raid As Raids, ByVal Type As Difficulty) As RaidCompletion
        Dim N As String = ""
        Dim T As String = ""

        Select Case Type
            Case Difficulty.Heroic
                If Raid = Raids.ToC Or Raid = Raids.ICC Or Raid = Raids.RS Or Raid = Raids.BD Or Raid = Raids.BoT Or Raid = Raids.TFW Or Raid = Raids.FL Then
                    T = "heroic"
                Else
                    Throw New Exception("Raid difficulty cannot be heroic")
                End If
            Case Difficulty.Normal
                T = "normal"
        End Select

        Select Case Raid
            Case Raids.MC : N = "mc"
            Case Raids.BWL : N = "bwl"
            Case Raids.AQ10 : N = "aq10"
            Case Raids.AQ40 : N = "aq40"
            Case Raids.Kar : N = "kar"
            Case Raids.Mag : N = "mag"
            Case Raids.Gru : N = "gru"
            Case Raids.SSC : N = "ssc"
            Case Raids.TK : N = "tk"
            Case Raids.MH : N = "mh"
            Case Raids.BT : N = "bt"
            Case Raids.SP : N = "sp"
            Case Raids.VoA : N = "voa"
            Case Raids.Nax : N = "nax"
            Case Raids.OS : N = "os"
            Case Raids.EoE : N = "eoe"
            Case Raids.Uld : N = "uld"
            Case Raids.Ony : N = "ony"
            Case Raids.ToC : N = "toc"
            Case Raids.ICC : N = "icc"
            Case Raids.RS : N = "rs"
            Case Raids.BH : N = "bh"
            Case Raids.BD : N = "bd"
            Case Raids.BoT : N = "bot"
            Case Raids.TFW : N = "tfw"
            Case Raids.FL : N = "fl"
        End Select

        Select Case Regex.Split(Regex.Split(ArmoryInfo, "class=""" & T & """>")(2), "data-raid=""" & N & """ class=""")(1).Split("""")(0)
            Case "status status-incomplete"
                Return RaidCompletion.Incomplete
            Case "status status-in-progress"
                Return RaidCompletion.InProgress
            Case "status status-completed"
                Return RaidCompletion.Completed
            Case Else
                Return Nothing
        End Select
    End Function

    Function BestRaidTitle() As String
        If ArmoryInfo.ToLower.Contains("most prestigious raid title") Then
            Return Regex.Split(Regex.Split(ArmoryInfo, "Most prestigious raid title:")(1), ">")(2).Split("<")(0)
        End If
    End Function
#End Region
End Class